package com.orcamento.service;

import java.util.List;

import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;

import com.orcamento.dao.GainDao;
import com.orcamento.entity.Account;
import com.orcamento.entity.Gain;
import com.orcamento.entity.enums.Month;
import com.orcamento.exception.NotFoundException;
import com.orcamento.exception.ServiceException;
import com.orcamento.service.filter.ListFilter;
import com.orcamento.util.CalendarUtil;

public class GainService {

	@Autowired
	private transient GainDao gainDao;
	
	@Autowired
	private transient AccountService accountService;

	public Gain save(Gain gain, Long accountId) throws ServiceException {
		try {
			Account account = accountService.findById(accountId);
			gain.setAccount(account);
			return gainDao.save(gain);
		} catch( Exception e ) {
			throw new ServiceException( "Ocorreu um erro ao salvar o Ganho.", e.getMessage() );
		}
	}

	public List<Gain> findByFilter(ListFilter filter, Long accountId) {
		if( filter.isAll() ) {
			return gainDao.findAllAndAccount(accountId);
		}
		
		Month month = Month.findById( CalendarUtil.getCurrentMonth() );
		DateTime startDate = CalendarUtil.toDate(1, month.id, CalendarUtil.getCurrentYear());
		DateTime endDate = CalendarUtil.toDate(month.maxDays, month.id, CalendarUtil.getCurrentYear());
		return gainDao.findBetweenByAccount(startDate, endDate, accountId);
	}

	public Gain findById(Long id, Long accountId) throws NotFoundException {
		Gain gain = gainDao.findByIdAndAccount(id, accountId);
		if( gain == null ) {
			throw new NotFoundException(id, "Gain");
		}
		return gain;
	}

	public Gain update(Gain gain, Long accountId) throws ServiceException, NotFoundException {
		Account account = accountService.findById(accountId);
		try {
			Gain gainToSave = findById( gain.getId(), accountId );
			gainToSave.setAccount(account);
			gainToSave.setReceivedDay( gain.getReceivedDay() );
			gainToSave.setValue( gain.getValue() );
			gainToSave.setEvent( gain.getEvent() );
			return gainDao.save(gainToSave);
		} catch(Exception e) {
			throw new ServiceException("Ocorreu um erro ao atualizar o Gain com ID: " + gain.getId(), e.getMessage());
		}
	}

	public void delete(Gain gain, Long accountId) throws ServiceException, NotFoundException {
		Gain gainToDelete = findById(gain.getId(), accountId);
		try {
			gainDao.delete( gainToDelete );
		} catch( Exception e ) {
			throw new ServiceException("Ocorreu um erro ao deletar o Gain " + gain.getId(), e.getMessage());
		}
	}

	public List<Gain> findBetween(DateTime start, DateTime limit, Long accountId) {
		return gainDao.findBetweenByAccount(start, limit, accountId);
	}

}
